package com.zhou.mvc;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 映射器（包含了大量的网址与方法的对应关系），封装了一个每一个uri所对应的映射对象
 */
public class HandleMapping {
    //key为uri 值为映射对象
    private static Map<String, MVCMapping> data = new HashMap<>();
    public static MVCMapping get(String uri){
        return data.get(uri);
    }
    public static void load(InputStream is) {
//        定义存储配置文件中的类信息的集合
        Properties ppt = new Properties();
        try {
            //装载后的数据结构与hashMap类似 key为配置文件的=左，值为=右（类路径）
            ppt.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获得所有类路径的集合
        Collection<Object> values = ppt.values();
        //遍历每一个包的项目路径
        for (Object cla : values) {
            String claasName = (String) cla;
            try {
                //加载配置文件中描述的每一个类
                Class c = Class.forName(claasName);
                //创建这个类的对象
                Object o = c.getConstructor().newInstance();
                //获取这个类的所有方法
                Method[] methods = c.getMethods();
                //遍历所有方法
                for (Method m : methods) {
                    //得到此方法上的所有注解
                    Annotation[] as = m.getAnnotations();
                    if (as != null) {
                        for (Annotation a : as) {
                            if (a instanceof ResponseBody) {
                                //说明此方法用于返回字符串给客户端
                                MVCMapping mapping = new MVCMapping(o,m,ResponseType.TEXT);
                                //key为uri 值为映射对象
                                MVCMapping put = data.put(((ResponseBody) a).value(), mapping);
                                if (put != null){
                                    //存在了重复的请求地址
                                    throw new RuntimeException("请求地址重复"+((ResponseBody) a).value());
                                }
                            } else if (a instanceof ResponseView) {
                                //说明此方法，用于返回界面给客户端
                                MVCMapping mapping = new MVCMapping(o,m,ResponseType.VIEW);
                                MVCMapping put = data.put(((ResponseView) a).value(), mapping);
                                if (put != null){
                                    //存在了重复的请求地址
                                    throw new RuntimeException("请求地址重复"+((ResponseView) a).value());
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 映射对象，每一个对象封装了一个方法，用于处理请求
     */
    public static class MVCMapping {
        private Object obj;
        private Method method;
        private ResponseType type;

        public MVCMapping() {
        }

        public MVCMapping(Object obj, Method method, ResponseType type) {
            this.obj = obj;
            this.method = method;
            this.type = type;
        }

        public Object getObj() {
            return obj;
        }

        public void setObj(Object obj) {
            this.obj = obj;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public ResponseType getType() {
            return type;
        }

        public void setType(ResponseType type) {
            this.type = type;
        }
    }
}
